#include "ZDataManager.h"

GLOBAL_NAMESPACE_BEGIN

template<> DataManager* Singleton<DataManager>::singleton_ = 0;

class ImageCmp
{
public:
    ImageCmp(ImageSpace::Image* lhs) : lhs_(lhs){}
    bool operator()(DataManager::ImageContainer::value_type rhs)
    {
        if (!lhs_) return false;
        if (lhs_->getFullPath().compare(rhs.second->getFullPath()) == 0)
            return true;
        return false;
    }

private:
    ImageSpace::Image* lhs_;
};

DataManager::DataManager()
{
    nDefaultImageCount_ = 0;
}

DataManager::~DataManager()
{
    destroy();
}

void DataManager::destroy()
{
    for (MeshList::iterator it = meshes_.begin(); it != meshes_.end(); ++it)
    {
        if (*it)
            delete (*it);
    }
    meshes_.clear();

    for (PointCloudList::iterator it = pointClouds_.begin(); it != pointClouds_.end(); ++it)
    {
        if (*it)
            delete (*it);
    }
    pointClouds_.clear();

    for (ImageContainer::iterator it = images_.begin(); it!=images_.end(); ++it)
    {
        if (it->second) delete it->second;
    }
    images_.clear();
    //imageManager_.clear();
    imageNames_.clear();
    nDefaultImageCount_ = 0;
}

void DataManager::clear()
{
    destroy();
}

void DataManager::init()
{

}

void DataManager::addMesh(MeshSpace::Mesh3D *mesh)
{
    if (mesh == NULL) return;

    meshes_.insert(meshes_.begin(), mesh);
}

MeshSpace::Mesh3D* DataManager::getMesh()
{
    if (meshes_.empty())
        return NULL;

    return (*meshes_.begin());
}

void DataManager::addPointCloud(MeshSpace::PointCloud* pc)
{
    if (pc == NULL) return;
    pointClouds_.insert(pointClouds_.begin(), pc);
}

MeshSpace::PointCloud* DataManager::getPointCloud()
{
    if (pointClouds_.empty())
        return NULL;

    return (*pointClouds_.begin());
}

void DataManager::addImage(ImageSpace::Image *ima, int id)
{
    if (ima == NULL) return;
    std::string fullname = ima->getFullPath();
    int realId = id;
    if (images_.find(fullname) != images_.end())
        return;

    if (id == -1)
    {
        realId = images_.size();
        ima->setId(realId);
        ima->modifyTheName();
    }
        //imageNames_[nId] = ima->getFullPath();
        //images_.insert(std::make_pair(fullname, ima));
        //if (ima->getType() == ImageSpace::Image::IMAGE_Default)
        //    nDefaultImageCount_++;
    else
    {
        ima->setId(id);
        ima->modifyTheName();
    }
    fullname = ima->getFullPath();
    imageNames_[realId] = fullname;
    images_.insert(std::make_pair(fullname, ima));
    if (ima->getType() == ImageSpace::Image::IMAGE_Default)
        nDefaultImageCount_++;
    
}

ImageSpace::Image* DataManager::readImage(const char* fileName, int id)
{
    ImageSpace::Image* ima = new ImageSpace::Image;
    if (ima->loadImageFromFile(fileName))
    {
        addImage(ima, id);
        return ima;
    }
    else
    {
        delete ima;
        return NULL;
    }
}

size_t DataManager::getImageCount()
{
    return images_.size();
}

size_t DataManager::getDefaultImageCount()
{
    return nDefaultImageCount_;
}

ImageSpace::Image* DataManager::getImageById(int idx)
{
    //if (idx<0 || idx>getImageCount())
    //    return NULL;
    if (imageNames_.find(idx) == imageNames_.end())
        return NULL;

    return images_[imageNames_[idx]];
}

void DataManager::removeImage(ImageSpace::Image* ima)
{
    ImageContainer::iterator findIt = images_.find(ima->getFullPath());
    if (findIt != images_.end())
    {
        images_.erase(findIt);
        imageNames_.erase(imageNames_.find(findIt->second->getId()));
        if (findIt->second->getType() == ImageSpace::Image::IMAGE_Default)
            nDefaultImageCount_--;
        delete ima;
        ima = NULL;
    }
    else
        return;
}

DataManager::ImageIterator DataManager::imageBeginIterator()
{
    return images_.begin();
}

DataManager::ImageIterator DataManager::imageEndIterator()
{
    return images_.end();
}

void DataManager::clearImageData()
{
    for (ImageContainer::iterator it = images_.begin(); it != images_.end(); ++it)
    {
        if (it->second) delete it->second;
    }
    images_.clear();
    imageNames_.clear();
    nDefaultImageCount_ = 0;
}

GLOBAL_NAMESPACE_END